package com.by.toolkit.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 流处理工具类
 *
 * @author liujun
 * @date 2023年06月12 4:01 PM
 */
public class ByMapUtil {

    private static Map<String, Object> extractMap(Map<String, Object> map) {

        Map<String, Object> resultMap = Maps.newHashMap();

        List<Map<String, Object>> iterList = Lists.newArrayList(map);
        for (int i = 0; ; i++) {
            Map<String, Object> iterMap = ByListUtil.getObjByIndex(iterList, i);
            if (Objects.isNull(iterMap)) {
                break;
            }
            for (Map.Entry<String, Object> entry : iterMap.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (value instanceof Map) {
                    Map<String, Object> stringObjectMap = ((Map<String, Object>) value).entrySet()
                            .stream()
                            .collect(Collectors.toMap(item -> SplitterUtil.UNDERSCORE_JOINER.join(key, item.getKey()), Map.Entry::getValue));
                    iterList.add(stringObjectMap);
                } else if (value instanceof List) {
                    resultMap.put(key,value);
                } else if (javaBase(value)) {
                    resultMap.put(key,value);
                }
                else {
                    iterList.add(BeanUtil.beanToMap(value).entrySet()
                            .stream()
                            .collect(Collectors.toMap(item -> SplitterUtil.UNDERSCORE_JOINER.join(key, item.getKey()), Map.Entry::getValue)));
                }
            }
        }

        return resultMap;
    }

    private static Boolean javaBase(Object value) {
        if (value instanceof Integer) {
            return true;
        } else if (value instanceof Double) {
            return true;
        } else if (value instanceof Boolean) {
            return true;
        } else if (value instanceof Character) {
            return true;
        } else if (value instanceof Byte) {
            return true;
        } else if (value instanceof Short) {
            return true;
        } else if (value instanceof Long) {
            return true;
        } else if (value instanceof Float) {
            return true;
        } else if (value instanceof String) {
            return true;
        }
        return false;
    }

    /**
     * a中的元素b中全部有并且相等则为true
     * @param mapA
     * @param mapB
     * @return
     */
    public static Boolean allContains(Map<String, Object> mapA,Map<String, Object> mapB){

        if (ObjectUtil.isAllEmpty(mapB,mapA)) {
            return false;
        }

        if (Objects.isNull(mapB)) {
            return true;
        }

        if (Objects.isNull(mapA)) {
            return false;
        }

        Map<String, Object> mapAExtract = extractMap(mapA);
        Map<String, Object> mapBExtract = extractMap(mapB);
        System.out.println(JSON.toJSONString(mapAExtract));
        System.out.println(JSON.toJSONString(mapBExtract));
        for (Map.Entry<String, Object> entry : mapAExtract.entrySet()) {
            String key = entry.getKey();
            Object valueB = mapBExtract.get(key);
            if (Objects.isNull(valueB)) {
                return false;
            }
            Object valueA = entry.getValue();
            if (Objects.equals(valueA,valueB)) {
                continue;
            }
            return false;
        }
        return true;
    }
}
